import $ from 'jquery'
import * as joint from 'jointjs'
import Element from './element'
import * as cc from '../util/constants'

/**
 * 输出节点
 */
const JointOutput = joint.shapes.basic.Output = joint.shapes.basic.Generic.extend({
    markup: '<g class="rotatable">' +
        `<rect class="background" width="${cc.ELEMENT_WIDTH}" height="${cc.ELEMENT_HEIGHT}" fill="none"/>` +
        '<path class="shadow st0" d="M35,6c-5.5,0-10,1.6-10,3.5v5v5v5c0,1.9,4.5,3.5,10,3.5s10-1.6,10-3.5v-5v-5v-5C45,7.6,40.5,6,35,6z"/>' +
        '<ellipse class="shadow st1" cx="35" cy="9.5" rx="10" ry="3.5"/>' +
        '<ellipse class="shadow st2" cx="45" cy="13.5" rx="10" ry="3.5"/>' +
        '<path class="shadow st3" d="M45,10c-5.5,0-10,1.6-10,3.5v5v5v5c0,1.9,4.5,3.5,10,3.5s10-1.6,10-3.5v-5v-5v-5C55,11.6,50.5,10,45,10z"/>' +
        '<ellipse class="shadow st0" cx="45" cy="13.5" rx="10" ry="3.5"/>' +
        '<path class="stroke" d="M44.6,28.4L41,24.9c-0.6-0.6-1.5-0.6-2.1,0s-0.6,1.5,0,2.1l1,1H36c-2.2,0-4-1.8-4-4v-6.5c0-0.8-0.7-1.5-1.5-1.5 S29,16.7,29,17.5V25c0,3.3,2.7,6,6,6h4.8l-0.9,0.9c-0.6,0.6-0.6,1.5,0,2.1s1.5,0.6,2.1,0l3.5-3.5C45.1,29.9,45.1,29,44.6,28.4z"/>' +

        '</g>',
    defaults: joint.util.deepSupplement({
        type: 'basic.Output',
        attrs: {
            size: {
                width: cc.ELEMENT_WIDTH,
                height: cc.ELEMENT_HEIGHT,
            },
            ".stroke": {},
            '.st0': {
                opacity: 0.3
            },
            '.st1': {
                opacity: 0.2
            },
            '.st2': {
                opacity: 0.35
            },
            '.st3': {
                opacity: 0.31
            },
        }
    }, joint.shapes.basic.Generic.prototype.defaults)
})

class Output extends Element {
    constructor(...args) {
        super(...args)
        this._jointInstance = new JointOutput(this.jointAttrs)
    }

    mixinAttr() {
        let mixin = {
            attrs: {
                '.stroke': {
                    stroke: 'none',
                    fill: 'none',
                },
                '.shadow': {
                    stroke: 'none',
                    fill: 'none',
                }
            }
        }
        $.extend(this.jointAttrs, mixin)
    }

    bindEvent() {
        super.bindEvent()
        this.$mask.on('mousedown', '.execute-action i', event => {
            this.$mask.trigger('execute_node', [this])
            event.preventDefault()
        })

        this.$mask.on('mousedown', '.action-toggle', event => {
            this.$mask.find('.execute-action').addClass('hide')
        })
    }

    setColor(colorIndex) {
        super.setColor(colorIndex)
        let color = this.getColorFromIndex(colorIndex)
        this.jointInstance.attr('.stroke/fill', color)
        this.jointInstance.attr('.shadow/fill', color)
    }

    set showDropActionMenu(flag) {
        if (this._showDropActionMenu === flag) {
            return
        }
        this._showDropActionMenu = flag
        if (flag) {
            if (this.$mask.find('.drag-action').length == 0) {
                let relinkFlag = !this.hasEnoughIncomingNodes()
                let dragError = this.parent.draggingElement.hasError
                var menu = '<div class="drag-action">';
                let relinkHtml = !dragError && relinkFlag ? '<div class="action link-action">连线</div>' : ''
                var menu = '<div class="drag-action">' + relinkHtml + "</div>"
                this.$mask.append(menu)
                this.$text.addClass('hide')
            }
        } else {
            this.$mask.find('.drag-action').remove()
            this.$text.removeClass('hide')
        }
    }

    set showActionMenu(flag) {
        if (this.parent.readOnly) { // 图是只读时，不显示
            return
        }
        // 只要没有错误，执行按钮总是显示；反之总是隐藏。不根据flag显示
        var hasEnoughIncomingNodes = this.hasEnoughIncomingNodes()
        var notRendered = this.$mask.find('.element-action.align-right').length == 0
        if (hasEnoughIncomingNodes && !this.hasError) {
            if (notRendered) {
                this.$mask.append('<div class="element-action align-right"><span class="execute-action"><i class="ygmat-execute"></i></span></div></div>')
            }
            this.$mask.find('.execute-action').removeClass('hide')
        } else {
            this.$mask.find('.element-action.align-right').remove()
        }

        // + 号菜单根据flag 显示
        if (this._showActionMenu === flag) {
            return
        }
        this._showActionMenu = flag
        if (flag) {
            // 节点设置为不能编辑或不能移除时，则不渲染移除节点选项
            let removeHtml = this.model.editAble !== false && this.model.removeable !== false ? '<li class="action-item remove-action">移除节点</li>' : ''
            var menu = `<div class="element-action "><span class="action-toggle">${cc.ICON_PLUS}</span><ul class="action-menu">` +
                removeHtml +
                '<li class="action-item color-action">设置颜色</li>' +
                '</ul></div></div>'
            this.$mask.append(menu)
        } else {
            this.$mask.find('.element-action:not(.align-right)').remove()
        }
    }

    createText() {
        super.createText()
        if (!this.model.editAble) {
            this.$text.find('.text').addClass('readonly')
        }
    }
}

export default Output